#include <scannerthread.h>
#include <QVector>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <debuglog.h>
ScannerThread::ScannerThread(QObject *parent) : QThread(parent)
{
    debugLog = new DebugLog();
    scannerPort = new QSerialPort(this);
    threadFlag = true;
    isOpen = false;
    openTime = QDateTime::currentMSecsSinceEpoch();
    timeOut = 1000 * 10;
    HeaderFlag = 0;
    ReadIndex = 0;
    openSerialPort();
    gpio_export();
    gpio_direction();
    gpio_writerHigh();
    scannerPort->moveToThread(this);
}

void ScannerThread::run()
{
    debugLog->writelog("Thread Scanner Run");
    connect(scannerPort, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(handleError(QSerialPort::SerialPortError)));
    //connect(scannerPort, SIGNAL(readyRead()), this, SLOT(readData()));
    while(threadFlag)
    {
        try
        {
            if(isOpen)
            {
                QByteArray data = scannerPort->readAll();
                if(!data.isNull() && data.length() > 0)
                {
                    for(int i = 0; i < data.length(); i++)
                    {
                        quint8 num = static_cast<quint8>(data.at(i));

                        if(HeaderFlag == 0){

                            if(ReadIndex ==0 && num == 55)
                            {
                                ReadIndex = 1;
                                ComData.clear();
                                ComData.append(data.at(i));
                            }
                            else if(ReadIndex == 1 && num == 54) {
                                HeaderFlag = 1;
                                ReadIndex = 2;
                                ComData.append(data.at(i));
                            }
                            else {
                                HeaderFlag = 0;
                                ReadIndex = 0;
                                ComData.clear();
                            }
                        }
                        else{
                            ReadIndex++;
                            ComData.append(data.at(i));

                            if(ReadIndex == 18){

                                QByteArray result;
                                result.resize(ComData.count());
                                for(int k = 0; k < ComData.count(); k++)
                                {
                                    result[k] = ComData.at(k);
                                }

                                emit ScannerSignal(result);
                                debugLog->infoLog("Scanner Serial Port Recive Data");
                                closeScanner();

                                HeaderFlag = 0;
                                ReadIndex = 0;
                                ComData.clear();
                            }
                            else if(ReadIndex > 18){
                                HeaderFlag = 0;
                                ReadIndex = 0;
                                ComData.clear();
                            }
                        }
                    }
                }
                else
                {
                    qint64 times = QDateTime::currentMSecsSinceEpoch();
                    if((times - openTime) >= timeOut)
                    {
                        debugLog->infoLog("Timeout Scanner Close");
                        closeScanner();
                    }
                }
            }
        }
        catch (QString exception)
        {
        }
        usleep(500);
    }
}

void ScannerThread::stop()
{
    threadFlag = false;
}

void ScannerThread::sendData(const QByteArray &data)
{
    writeData(data);
}

void ScannerThread::openSerialPort()
{
    scannerPort->setPortName("ttyO2");
    scannerPort->setBaudRate(QSerialPort::Baud9600);
    scannerPort->setDataBits(QSerialPort::Data8);
    scannerPort->setParity(QSerialPort::NoParity);
    scannerPort->setStopBits(QSerialPort::OneStop);
    scannerPort->setFlowControl(QSerialPort::NoFlowControl);
    if (scannerPort->open(QIODevice::ReadWrite)) {
        debugLog->writelog("Open Scanner Serial Success");
    } else {
        debugLog->writelog("Open Scanner Serial Error");
    }
}

void ScannerThread::closeSerialPort()
{
    if (scannerPort->isOpen())
        scannerPort->close();
}

void ScannerThread::writeData(const QByteArray &data)
{
    if (scannerPort->isOpen())
        scannerPort->write(data);
}

void ScannerThread::handleError(QSerialPort::SerialPortError error)
{
    if (error == QSerialPort::ResourceError) {
        debugLog->writelog("Scanner Serial Error:" + scannerPort->errorString());
        closeSerialPort();
    }
}

void ScannerThread::readData()
{
    QByteArray data = scannerPort->readAll();
    if(!data.isNull() && data.length() > 0)
    {
        debugLog->infoLog("Scanner Serial Port Recive Data");
        emit ScannerSignal(data);
        closeScanner();
    }
}

void ScannerThread::gpio_export()
{
    int fd = open(GPIO_EXPORT, O_WRONLY);
    if(fd == -1)
    {
        debugLog->errLog("Open GPIO Export Error");
        return;
    }
    write(fd, GPIO_PIN_VAL, sizeof(GPIO_PIN_VAL));
    close(fd);
    debugLog->infoLog("Set GPIO Export Success");
}

void ScannerThread::gpio_direction()
{
    int fd = open(GPIO_DIR, O_WRONLY);
    if(fd == -1)
    {
        debugLog->errLog("Open GPIO Direction Error");
        return;
    }
    write(fd, GPIO_DIR_VAL, sizeof(GPIO_DIR_VAL));
    close(fd);
    debugLog->infoLog("Set GPIO Direction Success");
}

void ScannerThread::gpio_writerHigh()
{
    int fd = open(GPIO_RST_VAL, O_RDWR);
    if(fd == -1)
    {
        debugLog->errLog("Open GPIO High Error");
        return;
    }
    write(fd, GPIO_RST_VAL_H, sizeof(GPIO_RST_VAL_H));
    close(fd);
    debugLog->infoLog("GPIO Set High");
}

void ScannerThread::gpio_writerLow()
{
    int fd = open(GPIO_RST_VAL, O_RDWR);
    if(fd == -1)
    {
        debugLog->errLog("Open GPIO Low Error");
        return;
    }
    write(fd, GPIO_RST_VAL_L, sizeof(GPIO_RST_VAL_L));
    close(fd);
    debugLog->infoLog("GPIO Set Low");
}

void ScannerThread::openScanner()
{
    debugLog->infoLog("Open Scanner");
    gpio_writerLow();
    // timeout delay
    openTime = QDateTime::currentMSecsSinceEpoch();
    isOpen = true;
}

void ScannerThread::closeScanner()
{
    debugLog->infoLog("Close Scanner");
    gpio_writerHigh();
    isOpen = false;
    usleep(200);
}
